package pl.wroc.pwr.mss.server;

import javax.swing.SwingUtilities;

import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import pl.wroc.pwr.mss.server.ui.ServerGui;

/**
 * Definiuje punkt wejscia aplikacji serwerowej.
 * 
 * @author mjagus
 */
public class ServerMain
{
    /**
     * Sciezka do konfiguracji log4j.
     */
    private static final String LOG4J_PROPERTIES_PATH = "log4j.properties";

    /**
     * Sciezka do pliku definiujacego springowy kontekst aplikacji.
     */
    private static final String APPLICATION_CONTEXT_PATH = "server-context.xml";

    /**
     * Logger tej klasy.
     */
    private static final Logger log = Logger.getLogger(ServerMain.class);

    /**
     * Springowy kontekst aplikacji serwerowej.
     */
    private static ApplicationContext applicationContext;

    /**
     * Punkt wejscia dla aplikacji serwerowej.
     * 
     * @param args Argumenty linii komend
     */
    public static void main(String[] args)
    {
        System.setProperty("log4j.properties", LOG4J_PROPERTIES_PATH);

        applicationContext = new ClassPathXmlApplicationContext(APPLICATION_CONTEXT_PATH);

        Runtime.getRuntime().addShutdownHook(new ShutdownHook());

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                ServerGui gui = getApplicationContext().getBean(ServerGui.class);
                gui.setVisible(true);
            }
        });

        log.info("App initialized");
    }

    /**
     * @return Springowy kontekst aplikacji serwerowej
     */
    public static ApplicationContext getApplicationContext()
    {
        return applicationContext;
    }

    /**
     * Watek wykonujacy sie przed zakonczeniem aplikacji. Zwalnia zasoby
     * z sesji hibernate'a.
     * 
     * @author mjagus
     */
    private static class ShutdownHook extends Thread
    {
        /**
         * Iniciuje watek z konkretna nazwa.
         */
        public ShutdownHook()
        {
            super("Shutdown Thread");
        }

        @Override
        public void run()
        {
            SessionFactory sessionFactory = (SessionFactory)getApplicationContext().getBean("commonSessionFactory");
            sessionFactory.getCurrentSession().beginTransaction();
            sessionFactory.getCurrentSession().getTransaction().commit();
            sessionFactory.getCurrentSession().disconnect();
            sessionFactory.getCurrentSession().close();
            sessionFactory.close();
            log.info("App shutdown");
        }
    }
}
